1/**
2 * Copyright (c) 2021 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 <binder/variable.h>
20#include <ir/base/classProperty.h>
21#include <ir/base/methodDefinition.h>
22#include <ir/expressions/privateIdentifier.h>
23#include <ir/ts/tsTypeReference.h>
24#include <util/bitset.h>
25
26namespace panda::es2panda::compiler {
27class PandaGen;
28}  // namespace panda::es2panda::compiler
29
30namespace panda::es2panda::checker {
31class Checker;
32class Type;
33}  // namespace panda::es2panda::checker
34
35namespace panda::es2panda::binder {
36class LocalScope;
37}  // namespace panda::es2panda::binder
38
39namespace panda::es2panda::ir {
40
41enum class FieldType : uint16_t {
42    NONE = 0,
43    NUMBER = (1 << 0),
44    STRING = (1 << 1),
45    BOOLEAN = (1 << 2),
46    TS_TYPE_REF = (1 << 3),
47    BIGINT = (1 << 4),
48    GENERIC = (1 << 5), // import type / type parameter
49    TS_NULL = (1 << 6),
50    TS_UNDEFINED = (1 << 7),
51};
52DEFINE_BITOPS(FieldType)
53
54class Identifier;
55class MethodDefinition;
56class TSTypeParameterDeclaration;
57class TSTypeParameterInstantiation;
58class TSClassImplements;
59class TSIndexSignature;
60
61class ClassDefinition : public AstNode {
62public:
63    explicit ClassDefinition(binder::ClassScope *scope, Identifier *ident, TSTypeParameterDeclaration *typeParams,
64                             TSTypeParameterInstantiation *superTypeParams,
65                             ArenaVector<TSClassImplements *> &&implements, MethodDefinition *ctor,
66                             MethodDefinition *staticInitializer, MethodDefinition *instanceInitializer,
67                             Expression *superClass, ArenaVector<Statement *> &&body,
68                             ArenaVector<TSIndexSignature *> &&indexSignatures, bool declare, bool abstract)
69        : AstNode(AstNodeType::CLASS_DEFINITION),
70          scope_(scope),
71          ident_(ident),
72          typeParams_(typeParams),
73          superTypeParams_(superTypeParams),
74          implements_(std::move(implements)),
75          ctor_(ctor),
76          staticInitializer_(staticInitializer),
77          instanceInitializer_(instanceInitializer),
78          superClass_(superClass),
79          body_(std::move(body)),
80          indexSignatures_(std::move(indexSignatures)),
81          declare_(declare),
82          abstract_(abstract),
83          exportDefault_(false),
84          isClassDecoratorPresent_(false)
85    {
86    }
87
88    binder::ClassScope *Scope() const
89    {
90        return scope_;
91    }
92
93    const Identifier *Ident() const
94    {
95        return ident_;
96    }
97
98    Identifier *Ident()
99    {
100        return ident_;
101    }
102
103    Expression *Super()
104    {
105        return superClass_;
106    }
107
108    const Expression *Super() const
109    {
110        return superClass_;
111    }
112
113    bool Declare() const
114    {
115        return declare_;
116    }
117
118    bool Abstract() const
119    {
120        return abstract_;
121    }
122
123    void SetAsExportDefault()
124    {
125        exportDefault_ = true;
126    }
127
128    ArenaVector<Statement *> &Body()
129    {
130        return body_;
131    }
132
133    const ArenaVector<Statement *> &Body() const
134    {
135        return body_;
136    }
137
138    void AddToBody(Statement *statement)
139    {
140        body_.push_back(statement);
141    }
142
143    TSTypeParameterDeclaration *TypeParams()
144    {
145        return typeParams_;
146    }
147
148    const TSTypeParameterDeclaration *TypeParams() const
149    {
150        return typeParams_;
151    }
152
153    ArenaVector<TSClassImplements *> &Implements()
154    {
155        return implements_;
156    }
157
158    const ArenaVector<TSClassImplements *> &Implements() const
159    {
160        return implements_;
161    }
162
163    ArenaVector<TSIndexSignature *> &IndexSignatures()
164    {
165        return indexSignatures_;
166    }
167
168    const ArenaVector<TSIndexSignature *> &IndexSignatures() const
169    {
170        return indexSignatures_;
171    }
172
173    MethodDefinition *Ctor()
174    {
175        ASSERT(ctor_ != nullptr);
176        return ctor_;
177    }
178
179    MethodDefinition *StaticInitializer() const
180    {
181        return staticInitializer_;
182    }
183
184    MethodDefinition *InstanceInitializer() const
185    {
186        return instanceInitializer_;
187    }
188
189    const TSTypeParameterInstantiation *SuperTypeParams() const
190    {
191        return superTypeParams_;
192    }
193
194    TSTypeParameterInstantiation *SuperTypeParams()
195    {
196        return superTypeParams_;
197    }
198
199    bool NeedStaticInitializer() const
200    {
201        return needStaticInitializer_;
202    }
203
204    bool NeedInstanceInitializer() const
205    {
206        return needInstanceInitializer_;
207    }
208
209    uint32_t GetSlot(const Expression *key) const
210    {
211        return scope_->GetSlot(key);
212    }
213
214    bool HasInstancePrivateMethod() const
215    {
216        return scope_->instanceMethodValidation_ != 0;
217    }
218
219    bool HasStaticPrivateMethod() const
220    {
221        return scope_->staticMethodValidation_ != 0;
222    }
223
224    void SetSendable()
225    {
226        isSendable_ = true;
227    }
228
229    bool IsSendable() const
230    {
231        return isSendable_;
232    }
233
234    void SetClassDecoratorPresent()
235    {
236        isClassDecoratorPresent_ = true;
237    }
238
239    bool IsClassDecoratorPresent() const
240    {
241        return isClassDecoratorPresent_;
242    }
243
244    const FunctionExpression *Ctor() const;
245
246    util::StringView GetName() const;
247
248    void BuildClassEnvironment(bool useDefineSemantic);
249
250    void Iterate(const NodeTraverser &cb) const override;
251    void Dump(ir::AstDumper *dumper) const override;
252    void Compile(compiler::PandaGen *pg) const override;
253    checker::Type *Check(checker::Checker *checker) const override;
254    void UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) override;
255    const ir::AstNode *GetDeclNodeFromIdentifier(const ir::Identifier *identifier) const;
256
257private:
258    compiler::VReg CompileHeritageClause(compiler::PandaGen *pg) const;
259    void InitializeClassName(compiler::PandaGen *pg) const;
260    int32_t CreateClassPublicBuffer(compiler::PandaGen *pg, util::BitSet &compiled, int32_t fieldTypeBufIdx = 0) const;
261    int32_t CreateClassPrivateBuffer(compiler::PandaGen *pg) const;
262    void CompileMissingProperties(compiler::PandaGen *pg, const util::BitSet &compiled, compiler::VReg classReg) const;
263    void StaticInitialize(compiler::PandaGen *pg, compiler::VReg classReg) const;
264    void InstanceInitialize(compiler::PandaGen *pg, compiler::VReg classReg) const;
265    void CompileComputedKeys(compiler::PandaGen *pg) const;
266    void AddFieldType(FieldType &fieldType, const Expression *typeAnnotation, compiler::PandaGen *pg) const;
267    void AddFieldTypeForTypeReference(const TSTypeReference *typeReference, FieldType &fieldType,
268                                      compiler::PandaGen *pg) const;
269    bool IsTypeParam(const util::StringView &propertyName) const;
270    int32_t CreateFieldTypeBuffer(compiler::PandaGen *pg) const;
271    void CompileSendableClass(compiler::PandaGen *pg) const;
272    void CompileGetterOrSetter(compiler::PandaGen *pg, compiler::VReg dest, const MethodDefinition *prop) const;
273
274    binder::ClassScope *scope_;
275    Identifier *ident_;
276    TSTypeParameterDeclaration *typeParams_;
277    TSTypeParameterInstantiation *superTypeParams_;
278    ArenaVector<TSClassImplements *> implements_;
279    MethodDefinition *ctor_;
280    MethodDefinition *staticInitializer_;
281    MethodDefinition *instanceInitializer_;
282    Expression *superClass_;
283    ArenaVector<Statement *> body_;
284    ArenaVector<TSIndexSignature *> indexSignatures_;
285    bool declare_;
286    bool abstract_;
287    bool exportDefault_;
288    bool needStaticInitializer_ {false};
289    bool needInstanceInitializer_ {false};
290    bool hasComputedKey_ {false};
291    bool hasPrivateElement_ {false};
292    bool isSendable_ {false};
293    bool isClassDecoratorPresent_ {false};
294};
295
296}  // namespace panda::es2panda::ir
297
298#endif
299