1/** 2 * Copyright (c) 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#include "evaluate/debugInfoDeserialization/classBuilder.h" 17#include "parser/program/program.h" 18#include "checker/ETSchecker.h" 19#include "ir/statements/classDeclaration.h" 20#include "ir/expressions/identifier.h" 21#include "libpandafile/class_data_accessor-inl.h" 22#include "libpandafile/file-inl.h" 23#include "libpandafile/method_data_accessor.h" 24#include "evaluate/helpers.h" 25#include "evaluate/debugInfoDeserialization/methodBuilder.h" 26 27namespace ark::es2panda::evaluate { 28 29ClassBuilder::ClassBuilder(checker::ETSChecker *checker, util::StringView name, panda_file::ClassDataAccessor &cda, 30 ir::Expression *superClass) 31 : checker_(checker), className_(name), cda_(cda), superClass_(superClass) 32{ 33 classModifiers_ = ir::ClassDefinitionModifiers::ID_REQUIRED | ir::ClassDefinitionModifiers::CLASS_DECL | 34 ir::ClassDefinitionModifiers::DECLARATION; 35 if (superClass_ != nullptr) { 36 classModifiers_ |= ir::ClassDefinitionModifiers::HAS_SUPER; 37 } 38 39 modifierFlags_ = helpers::GetModifierFlags(cda); 40} 41 42ir::ClassDeclaration *ClassBuilder::Build(parser::Program *program) && 43{ 44 auto *allocator = checker_->Allocator(); 45 ArenaVector<ir::AstNode *> classBody(allocator->Adapter()); 46 47 BuildFields(classBody); 48 BuildMethods(classBody); 49 50 // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) 51 auto *classId = checker_->AllocNode<ir::Identifier>(className_, allocator); 52 classId->SetReference(); 53 54 // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) 55 auto *classDef = checker_->AllocNode<ir::ClassDefinition>( 56 util::StringView(), classId, nullptr, nullptr, ArenaVector<ir::TSClassImplements *>(allocator->Adapter()), 57 nullptr, superClass_, ArenaVector<ir::AstNode *>(allocator->Adapter()), classModifiers_, modifierFlags_, 58 ToLanguage(program->Extension())); 59 60 // Set parents for all class'es fields and methods. 61 classDef->AddProperties(std::move(classBody)); 62 63 // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) 64 auto *classDecl = checker_->AllocNode<ir::ClassDeclaration>(classDef, allocator); 65 // Declare everything as exported for correct import resolution. 66 classDecl->AddModifier(ir::ModifierFlags::EXPORT); 67 68 auto *programAst = program->Ast(); 69 classDecl->SetParent(programAst); 70 // Here we assume that global statements of the passed `program` are not currently checked, so that 71 // insertion is safe. 72 programAst->Statements().push_back(classDecl); 73 74 return classDecl; 75} 76 77void ClassBuilder::BuildFields(ArenaVector<ir::AstNode *> &classBody) 78{ 79 const auto &pf = cda_.GetPandaFile(); 80 81 cda_.EnumerateFields([&](panda_file::FieldDataAccessor &fda) -> void { 82 const char *name = utf::Mutf8AsCString(pf.GetStringData(fda.GetNameId()).data); 83 84 auto *typeNode = helpers::PandaTypeToTypeNode(pf, fda, checker_); 85 ASSERT(typeNode); 86 87 auto *field = helpers::CreateClassProperty(checker_, name, typeNode, helpers::GetModifierFlags(fda, true)); 88 classBody.push_back(field); 89 }); 90} 91 92void ClassBuilder::BuildMethods(ArenaVector<ir::AstNode *> &classBody) 93{ 94 cda_.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) -> void { 95 auto *method = MethodBuilder(checker_, mda, modifierFlags_).Build(); 96 classBody.push_back(method); 97 }); 98} 99 100} // namespace ark::es2panda::evaluate 101