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