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