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_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 26 namespace panda::es2panda::compiler { 27 class PandaGen; 28 } // namespace panda::es2panda::compiler 29 30 namespace panda::es2panda::checker { 31 class Checker; 32 class Type; 33 } // namespace panda::es2panda::checker 34 35 namespace panda::es2panda::binder { 36 class LocalScope; 37 } // namespace panda::es2panda::binder 38 39 namespace panda::es2panda::ir { 40 41 enum 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 }; 52 DEFINE_BITOPS(FieldType) 53 54 class Identifier; 55 class MethodDefinition; 56 class TSTypeParameterDeclaration; 57 class TSTypeParameterInstantiation; 58 class TSClassImplements; 59 class TSIndexSignature; 60 61 class ClassDefinition : public AstNode { 62 public: ClassDefinition(binder::ClassScope * scope,Identifier * ident,TSTypeParameterDeclaration * typeParams,TSTypeParameterInstantiation * superTypeParams,ArenaVector<TSClassImplements * > && implements,MethodDefinition * ctor,MethodDefinition * staticInitializer,MethodDefinition * instanceInitializer,Expression * superClass,ArenaVector<Statement * > && body,ArenaVector<TSIndexSignature * > && indexSignatures,bool declare,bool abstract)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 Scope()88 binder::ClassScope *Scope() const 89 { 90 return scope_; 91 } 92 Ident()93 const Identifier *Ident() const 94 { 95 return ident_; 96 } 97 Ident()98 Identifier *Ident() 99 { 100 return ident_; 101 } 102 Super()103 Expression *Super() 104 { 105 return superClass_; 106 } 107 Super()108 const Expression *Super() const 109 { 110 return superClass_; 111 } 112 Declare()113 bool Declare() const 114 { 115 return declare_; 116 } 117 Abstract()118 bool Abstract() const 119 { 120 return abstract_; 121 } 122 SetAsExportDefault()123 void SetAsExportDefault() 124 { 125 exportDefault_ = true; 126 } 127 Body()128 ArenaVector<Statement *> &Body() 129 { 130 return body_; 131 } 132 Body()133 const ArenaVector<Statement *> &Body() const 134 { 135 return body_; 136 } 137 AddToBody(Statement * statement)138 void AddToBody(Statement *statement) 139 { 140 body_.push_back(statement); 141 } 142 TypeParams()143 TSTypeParameterDeclaration *TypeParams() 144 { 145 return typeParams_; 146 } 147 TypeParams()148 const TSTypeParameterDeclaration *TypeParams() const 149 { 150 return typeParams_; 151 } 152 Implements()153 ArenaVector<TSClassImplements *> &Implements() 154 { 155 return implements_; 156 } 157 Implements()158 const ArenaVector<TSClassImplements *> &Implements() const 159 { 160 return implements_; 161 } 162 IndexSignatures()163 ArenaVector<TSIndexSignature *> &IndexSignatures() 164 { 165 return indexSignatures_; 166 } 167 IndexSignatures()168 const ArenaVector<TSIndexSignature *> &IndexSignatures() const 169 { 170 return indexSignatures_; 171 } 172 Ctor()173 MethodDefinition *Ctor() 174 { 175 ASSERT(ctor_ != nullptr); 176 return ctor_; 177 } 178 StaticInitializer()179 MethodDefinition *StaticInitializer() const 180 { 181 return staticInitializer_; 182 } 183 InstanceInitializer()184 MethodDefinition *InstanceInitializer() const 185 { 186 return instanceInitializer_; 187 } 188 SuperTypeParams()189 const TSTypeParameterInstantiation *SuperTypeParams() const 190 { 191 return superTypeParams_; 192 } 193 SuperTypeParams()194 TSTypeParameterInstantiation *SuperTypeParams() 195 { 196 return superTypeParams_; 197 } 198 NeedStaticInitializer()199 bool NeedStaticInitializer() const 200 { 201 return needStaticInitializer_; 202 } 203 NeedInstanceInitializer()204 bool NeedInstanceInitializer() const 205 { 206 return needInstanceInitializer_; 207 } 208 GetSlot(const Expression * key)209 uint32_t GetSlot(const Expression *key) const 210 { 211 return scope_->GetSlot(key); 212 } 213 HasInstancePrivateMethod()214 bool HasInstancePrivateMethod() const 215 { 216 return scope_->instanceMethodValidation_ != 0; 217 } 218 HasStaticPrivateMethod()219 bool HasStaticPrivateMethod() const 220 { 221 return scope_->staticMethodValidation_ != 0; 222 } 223 SetSendable()224 void SetSendable() 225 { 226 isSendable_ = true; 227 } 228 IsSendable()229 bool IsSendable() const 230 { 231 return isSendable_; 232 } 233 SetImplementFromEts()234 void SetImplementFromEts() 235 { 236 isImplementFromEts_ = true; 237 } 238 IsImplementFromEts()239 bool IsImplementFromEts() const 240 { 241 return isImplementFromEts_; 242 } 243 SetClassDecoratorPresent()244 void SetClassDecoratorPresent() 245 { 246 isClassDecoratorPresent_ = true; 247 } 248 IsClassDecoratorPresent()249 bool IsClassDecoratorPresent() const 250 { 251 return isClassDecoratorPresent_; 252 } 253 IncreasePropertyCount()254 void IncreasePropertyCount() 255 { 256 ++classExpectedPropertyCount_; 257 } 258 ExpectedPropertyCount()259 size_t ExpectedPropertyCount() const 260 { 261 return classExpectedPropertyCount_; 262 } 263 SetEtsImplementsMessage(util::StringView message)264 void SetEtsImplementsMessage(util::StringView message) 265 { 266 etsImplementsMessage_ = message; 267 } 268 GetEtsImplementsMessage()269 util::StringView GetEtsImplementsMessage() const 270 { 271 return etsImplementsMessage_; 272 } 273 274 void CalculateClassExpectedPropertyCount(); 275 void ProcessClassProperty(const ClassProperty *prop, 276 const std::function<void(const util::StringView&)>& addPropertyName); 277 void ProcessConstructorBody(const BlockStatement *body, 278 const std::function<void(const util::StringView&)>& addPropertyName); 279 void ProcessPropertyKey(const Expression* key, 280 const std::function<void(const util::StringView&)>& addPropertyName); 281 282 const FunctionExpression *Ctor() const; 283 284 util::StringView GetName() const; 285 286 void BuildClassEnvironment(bool useDefineSemantic); 287 288 void Iterate(const NodeTraverser &cb) const override; 289 void Dump(ir::AstDumper *dumper) const override; 290 void Compile(compiler::PandaGen *pg) const override; 291 checker::Type *Check(checker::Checker *checker) const override; 292 void UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) override; 293 const ir::AstNode *GetDeclNodeFromIdentifier(const ir::Identifier *identifier) const; 294 295 private: 296 compiler::VReg CompileHeritageClause(compiler::PandaGen *pg) const; 297 void InitializeClassName(compiler::PandaGen *pg) const; 298 int32_t CreateClassPublicBuffer(compiler::PandaGen *pg, util::BitSet &compiled, int32_t fieldTypeBufIdx = 0) const; 299 int32_t CreateClassPrivateBuffer(compiler::PandaGen *pg) const; 300 void CompileMissingProperties(compiler::PandaGen *pg, const util::BitSet &compiled, compiler::VReg classReg) const; 301 void StaticInitialize(compiler::PandaGen *pg, compiler::VReg classReg) const; 302 void InstanceInitialize(compiler::PandaGen *pg, compiler::VReg classReg) const; 303 void CompileComputedKeys(compiler::PandaGen *pg) const; 304 void AddFieldType(FieldType &fieldType, const Expression *typeAnnotation, compiler::PandaGen *pg) const; 305 void AddFieldTypeForTypeReference(const TSTypeReference *typeReference, FieldType &fieldType, 306 compiler::PandaGen *pg) const; 307 bool IsTypeParam(const util::StringView &propertyName) const; 308 int32_t CreateFieldTypeBuffer(compiler::PandaGen *pg) const; 309 void CompileSendableClass(compiler::PandaGen *pg) const; 310 void CompileGetterOrSetter(compiler::PandaGen *pg, compiler::VReg dest, const MethodDefinition *prop) const; 311 312 binder::ClassScope *scope_; 313 Identifier *ident_; 314 TSTypeParameterDeclaration *typeParams_; 315 TSTypeParameterInstantiation *superTypeParams_; 316 ArenaVector<TSClassImplements *> implements_; 317 MethodDefinition *ctor_; 318 MethodDefinition *staticInitializer_; 319 MethodDefinition *instanceInitializer_; 320 Expression *superClass_; 321 ArenaVector<Statement *> body_; 322 ArenaVector<TSIndexSignature *> indexSignatures_; 323 bool declare_; 324 bool abstract_; 325 bool exportDefault_; 326 bool needStaticInitializer_ {false}; 327 bool needInstanceInitializer_ {false}; 328 bool hasComputedKey_ {false}; 329 bool hasPrivateElement_ {false}; 330 bool isSendable_ {false}; 331 bool isClassDecoratorPresent_ {false}; 332 bool isImplementFromEts_ {false}; 333 size_t classExpectedPropertyCount_ {0}; 334 util::StringView etsImplementsMessage_ {""}; 335 }; 336 337 } // namespace panda::es2panda::ir 338 339 #endif 340