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