• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_PARSER_INCLUDE_AST_CLASS_DEFINITION_H
17 #define ES2PANDA_PARSER_INCLUDE_AST_CLASS_DEFINITION_H
18 
19 #include "varbinder/scope.h"
20 #include "varbinder/variable.h"
21 #include "ir/astNode.h"
22 #include "ir/expressions/identifier.h"
23 #include "ir/srcDump.h"
24 #include "ir/statements/annotationUsage.h"
25 #include "util/language.h"
26 
27 namespace ark::es2panda::ir {
28 class ClassElement;
29 class Identifier;
30 class MethodDefinition;
31 class TSTypeParameterDeclaration;
32 class TSTypeParameterInstantiation;
33 class TSClassImplements;
34 class TSIndexSignature;
35 
36 using ENUMBITOPS_OPERATORS;
37 
38 enum class ClassDefinitionModifiers : uint32_t {
39     NONE = 0,
40     DECLARATION = 1U << 0U,
41     ID_REQUIRED = 1U << 1U,
42     GLOBAL = 1U << 2U,
43     HAS_SUPER = 1U << 3U,
44     SET_CTOR_ID = 1U << 4U,
45     EXTERN = 1U << 5U,
46     ANONYMOUS = 1U << 6U,
47     GLOBAL_INITIALIZED = 1U << 7U,
48     CLASS_DECL = 1U << 8U,
49     INNER = 1U << 9U,
50     FROM_EXTERNAL = 1U << 10U,
51     LOCAL = 1U << 11U,
52     CLASSDEFINITION_CHECKED = 1U << 12U,
53     DECLARATION_ID_REQUIRED = DECLARATION | ID_REQUIRED
54 };
55 
56 }  // namespace ark::es2panda::ir
57 
58 template <>
59 struct enumbitops::IsAllowedType<ark::es2panda::ir::ClassDefinitionModifiers> : std::true_type {
60 };
61 
62 namespace ark::es2panda::ir {
63 
64 class ClassDefinition : public TypedAstNode {
65 public:
66     ClassDefinition() = delete;
67     ~ClassDefinition() override = default;
68 
69     NO_COPY_SEMANTIC(ClassDefinition);
70     NO_MOVE_SEMANTIC(ClassDefinition);
71     // CC-OFFNXT(G.FUN.01-CPP) solid logic
72     explicit ClassDefinition(const util::StringView &privateId, Identifier *ident,
73                              TSTypeParameterDeclaration *typeParams, TSTypeParameterInstantiation *superTypeParams,
74                              ArenaVector<TSClassImplements *> &&implements, MethodDefinition *ctor,
75                              Expression *superClass, ArenaVector<AstNode *> &&body, ClassDefinitionModifiers modifiers,
76                              ModifierFlags flags, Language lang)
77         : TypedAstNode(AstNodeType::CLASS_DEFINITION, flags),
78           privateId_(privateId),
79           ident_(ident),
80           typeParams_(typeParams),
81           superTypeParams_(superTypeParams),
82           implements_(std::move(implements)),
83           ctor_(ctor),
84           superClass_(superClass),
85           body_(std::move(body)),
86           modifiers_(modifiers),
87           lang_(lang),
88           capturedVars_(body_.get_allocator()),
89           localVariableIsNeeded_(body_.get_allocator()),
90           localIndex_(classCounter_++),
91           localPrefix_("$" + std::to_string(localIndex_)),
92           annotations_(body_.get_allocator())
93     {
94     }
95     // CC-OFFNXT(G.FUN.01-CPP) solid logic
96     explicit ClassDefinition(ArenaAllocator *allocator, Identifier *ident, ArenaVector<AstNode *> &&body,
97                              ClassDefinitionModifiers modifiers, ModifierFlags flags, Language lang)
98         : TypedAstNode(AstNodeType::CLASS_DEFINITION, flags),
99           ident_(ident),
100           implements_(allocator->Adapter()),
101           body_(std::move(body)),
102           modifiers_(modifiers),
103           lang_(lang),
104           capturedVars_(allocator->Adapter()),
105           localVariableIsNeeded_(allocator->Adapter()),
106           localIndex_(classCounter_++),
107           localPrefix_("$" + std::to_string(localIndex_)),
108           annotations_(body_.get_allocator())
109     {
110     }
111 
112     explicit ClassDefinition(ArenaAllocator *allocator, Identifier *ident, ClassDefinitionModifiers modifiers,
113                              ModifierFlags flags, Language lang)
114         : TypedAstNode(AstNodeType::CLASS_DEFINITION, flags),
115           ident_(ident),
116           implements_(allocator->Adapter()),
117           body_(allocator->Adapter()),
118           modifiers_(modifiers),
119           lang_(lang),
120           capturedVars_(allocator->Adapter()),
121           localVariableIsNeeded_(allocator->Adapter()),
122           localIndex_(classCounter_++),
123           localPrefix_("$" + std::to_string(localIndex_)),
124           annotations_(body_.get_allocator())
125     {
126     }
127 
128     [[nodiscard]] bool IsScopeBearer() const noexcept override
129     {
130         return true;
131     }
132 
133     [[nodiscard]] varbinder::LocalScope *Scope() const noexcept override
134     {
135         return scope_;
136     }
137 
138     void SetScope(varbinder::LocalScope *scope)
139     {
140         ASSERT(scope_ == nullptr);
141         scope_ = scope;
142     }
143 
144     void ClearScope() noexcept override
145     {
146         scope_ = nullptr;
147     }
148 
149     [[nodiscard]] const Identifier *Ident() const noexcept
150     {
151         return ident_;
152     }
153 
154     [[nodiscard]] Identifier *Ident() noexcept
155     {
156         return ident_;
157     }
158 
159     void SetIdent(ir::Identifier *ident) noexcept;
160 
161     [[nodiscard]] const util::StringView &PrivateId() const noexcept
162     {
163         return privateId_;
164     }
165 
166     [[nodiscard]] const util::StringView &InternalName() const noexcept
167     {
168         return privateId_;
169     }
170 
171     void SetInternalName(util::StringView internalName) noexcept
172     {
173         privateId_ = internalName;
174     }
175 
176     [[nodiscard]] Expression *Super() noexcept
177     {
178         return superClass_;
179     }
180 
181     [[nodiscard]] const Expression *Super() const noexcept
182     {
183         return superClass_;
184     }
185 
186     void SetSuper(Expression *superClass)
187     {
188         superClass_ = superClass;
189         if (superClass_ != nullptr) {
190             superClass_->SetParent(this);
191         }
192     }
193 
194     [[nodiscard]] bool IsGlobal() const noexcept
195     {
196         return (modifiers_ & ClassDefinitionModifiers::GLOBAL) != 0;
197     }
198 
199     [[nodiscard]] bool IsLocal() const noexcept
200     {
201         return (modifiers_ & ClassDefinitionModifiers::LOCAL) != 0;
202     }
203 
204     [[nodiscard]] bool IsExtern() const noexcept
205     {
206         return (modifiers_ & ClassDefinitionModifiers::EXTERN) != 0;
207     }
208 
209     [[nodiscard]] bool IsFromExternal() const noexcept
210     {
211         return (modifiers_ & ClassDefinitionModifiers::FROM_EXTERNAL) != 0;
212     }
213     [[nodiscard]] bool IsInner() const noexcept
214     {
215         return (modifiers_ & ClassDefinitionModifiers::INNER) != 0;
216     }
217 
218     [[nodiscard]] bool IsGlobalInitialized() const noexcept
219     {
220         return (modifiers_ & ClassDefinitionModifiers::GLOBAL_INITIALIZED) != 0;
221     }
222 
223     [[nodiscard]] bool IsClassDefinitionChecked() const noexcept
224     {
225         return (modifiers_ & ClassDefinitionModifiers::CLASSDEFINITION_CHECKED) != 0;
226     }
227 
228     [[nodiscard]] es2panda::Language Language() const noexcept
229     {
230         return lang_;
231     }
232 
233     void SetGlobalInitialized() noexcept
234     {
235         modifiers_ |= ClassDefinitionModifiers::GLOBAL_INITIALIZED;
236     }
237 
238     void SetInnerModifier() noexcept
239     {
240         modifiers_ |= ClassDefinitionModifiers::INNER;
241     }
242 
243     void SetClassDefinitionChecked() noexcept
244     {
245         modifiers_ |= ClassDefinitionModifiers::CLASSDEFINITION_CHECKED;
246     }
247 
248     [[nodiscard]] ClassDefinitionModifiers Modifiers() const noexcept
249     {
250         return modifiers_;
251     }
252 
253     void SetModifiers(ClassDefinitionModifiers modifiers) noexcept
254     {
255         modifiers_ = modifiers;
256     }
257 
258     void AddProperties(ArenaVector<AstNode *> &&body)
259     {
260         for (auto *prop : body) {
261             prop->SetParent(this);
262         }
263 
264         body_.insert(body_.end(), body.begin(), body.end());
265     }
266 
267     [[nodiscard]] ArenaVector<AstNode *> &Body() noexcept
268     {
269         return body_;
270     }
271 
272     [[nodiscard]] const ArenaVector<AstNode *> &Body() const noexcept
273     {
274         return body_;
275     }
276 
277     [[nodiscard]] MethodDefinition *Ctor() noexcept
278     {
279         return ctor_;
280     }
281 
282     void SetCtor(MethodDefinition *ctor)
283     {
284         ctor_ = ctor;
285     }
286 
287     [[nodiscard]] ArenaVector<ir::TSClassImplements *> &Implements() noexcept
288     {
289         return implements_;
290     }
291 
292     [[nodiscard]] const ArenaVector<ir::TSClassImplements *> &Implements() const noexcept
293     {
294         return implements_;
295     }
296 
297     [[nodiscard]] const ir::TSTypeParameterDeclaration *TypeParams() const noexcept
298     {
299         return typeParams_;
300     }
301 
302     [[nodiscard]] ir::TSTypeParameterDeclaration *TypeParams() noexcept
303     {
304         return typeParams_;
305     }
306 
307     void SetTypeParams(ir::TSTypeParameterDeclaration *typeParams)
308     {
309         typeParams_ = typeParams;
310     }
311 
312     const TSTypeParameterInstantiation *SuperTypeParams() const
313     {
314         return superTypeParams_;
315     }
316 
317     TSTypeParameterInstantiation *SuperTypeParams()
318     {
319         return superTypeParams_;
320     }
321 
322     [[nodiscard]] static int LocalTypeCounter() noexcept
323     {
324         return classCounter_;
325     }
326 
327     [[nodiscard]] int LocalIndex() const noexcept
328     {
329         return localIndex_;
330     }
331 
332     [[nodiscard]] const std::string &LocalPrefix() const noexcept
333     {
334         return localPrefix_;
335     }
336 
337     bool CaptureVariable(varbinder::Variable *var)
338     {
339         return capturedVars_.insert(var).second;
340     }
341 
342     bool AddToLocalVariableIsNeeded(varbinder::Variable *var)
343     {
344         return localVariableIsNeeded_.insert(var).second;
345     }
346 
347     bool IsLocalVariableNeeded(varbinder::Variable *var) const
348     {
349         return localVariableIsNeeded_.find(var) != localVariableIsNeeded_.end();
350     }
351 
352     [[nodiscard]] const ArenaSet<varbinder::Variable *> &CapturedVariables() const noexcept
353     {
354         return capturedVars_;
355     }
356 
357     bool EraseCapturedVariable(varbinder::Variable *var)
358     {
359         return capturedVars_.erase(var) != 0;
360     }
361 
362     const ArenaVector<AnnotationUsage *> &Annotations() const
363     {
364         return annotations_;
365     }
366 
367     void SetAnnotations(ArenaVector<AnnotationUsage *> &&annotations)
368     {
369         annotations_ = std::move(annotations);
370         for (auto anno : annotations_) {
371             anno->SetParent(this);
372         }
373     }
374 
375     void SetOrigEnumDecl(ir::TSEnumDeclaration *enumDecl)
376     {
377         origEnumDecl_ = enumDecl;
378     }
379 
380     ir::TSEnumDeclaration *OrigEnumDecl() const
381     {
382         return origEnumDecl_;
383     }
384 
385     const FunctionExpression *Ctor() const;
386     bool HasPrivateMethod() const;
387     bool HasComputedInstanceField() const;
388     bool HasMatchingPrivateKey(const util::StringView &name) const;
389 
390     void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override;
391     void Iterate(const NodeTraverser &cb) const override;
392 
393     void Dump(ir::AstDumper *dumper) const override;
394     void Dump(ir::SrcDumper *dumper) const override;
395     void Compile(compiler::PandaGen *pg) const override;
396     void Compile(compiler::ETSGen *etsg) const override;
397     checker::Type *Check(checker::TSChecker *checker) override;
398     checker::Type *Check(checker::ETSChecker *checker) override;
399 
400     void Accept(ASTVisitorT *v) override
401     {
402         v->Accept(this);
403     }
404 
405     template <typename T>
406     static void DumpItems(ir::SrcDumper *dumper, const std::string &prefix, const ArenaVector<T *> &items)
407     {
408         if (items.empty()) {
409             return;
410         }
411         dumper->Add(prefix);
412         for (size_t i = 0; i < items.size(); ++i) {
413             items[i]->Dump(dumper);
414             if (i < items.size() - 1) {
415                 dumper->Add(", ");
416             }
417         }
418     }
419 
420 private:
421     void CompileStaticFieldInitializers(compiler::PandaGen *pg, compiler::VReg classReg,
422                                         const std::vector<compiler::VReg> &staticComputedFieldKeys) const;
423 
424     // This method is needed by OHOS CI code checker
425     void DumpBody(ir::SrcDumper *dumper) const;
426 
427     varbinder::LocalScope *scope_ {nullptr};
428     util::StringView privateId_ {};
429     Identifier *ident_ {};
430     TSTypeParameterDeclaration *typeParams_ {};
431     TSTypeParameterInstantiation *superTypeParams_ {};
432     ArenaVector<TSClassImplements *> implements_;
433     MethodDefinition *ctor_ {};
434     Expression *superClass_ {};
435     ArenaVector<AstNode *> body_;
436     ClassDefinitionModifiers modifiers_;
437     es2panda::Language lang_;
438     ArenaSet<varbinder::Variable *> capturedVars_;
439     ArenaSet<varbinder::Variable *> localVariableIsNeeded_;
440     TSEnumDeclaration *origEnumDecl_ {};
441     static int classCounter_;
442     const int localIndex_ {};
443     const std::string localPrefix_ {};
444     ArenaVector<AnnotationUsage *> annotations_;
445 };
446 }  // namespace ark::es2panda::ir
447 
448 #endif
449