13af6ab5fSopenharmony_ci/**
23af6ab5fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ci#include "evaluate/debugInfoDeserialization/classBuilder.h"
173af6ab5fSopenharmony_ci#include "parser/program/program.h"
183af6ab5fSopenharmony_ci#include "checker/ETSchecker.h"
193af6ab5fSopenharmony_ci#include "ir/statements/classDeclaration.h"
203af6ab5fSopenharmony_ci#include "ir/expressions/identifier.h"
213af6ab5fSopenharmony_ci#include "libpandafile/class_data_accessor-inl.h"
223af6ab5fSopenharmony_ci#include "libpandafile/file-inl.h"
233af6ab5fSopenharmony_ci#include "libpandafile/method_data_accessor.h"
243af6ab5fSopenharmony_ci#include "evaluate/helpers.h"
253af6ab5fSopenharmony_ci#include "evaluate/debugInfoDeserialization/methodBuilder.h"
263af6ab5fSopenharmony_ci
273af6ab5fSopenharmony_cinamespace ark::es2panda::evaluate {
283af6ab5fSopenharmony_ci
293af6ab5fSopenharmony_ciClassBuilder::ClassBuilder(checker::ETSChecker *checker, util::StringView name, panda_file::ClassDataAccessor &cda,
303af6ab5fSopenharmony_ci                           ir::Expression *superClass)
313af6ab5fSopenharmony_ci    : checker_(checker), className_(name), cda_(cda), superClass_(superClass)
323af6ab5fSopenharmony_ci{
333af6ab5fSopenharmony_ci    classModifiers_ = ir::ClassDefinitionModifiers::ID_REQUIRED | ir::ClassDefinitionModifiers::CLASS_DECL |
343af6ab5fSopenharmony_ci                      ir::ClassDefinitionModifiers::DECLARATION;
353af6ab5fSopenharmony_ci    if (superClass_ != nullptr) {
363af6ab5fSopenharmony_ci        classModifiers_ |= ir::ClassDefinitionModifiers::HAS_SUPER;
373af6ab5fSopenharmony_ci    }
383af6ab5fSopenharmony_ci
393af6ab5fSopenharmony_ci    modifierFlags_ = helpers::GetModifierFlags(cda);
403af6ab5fSopenharmony_ci}
413af6ab5fSopenharmony_ci
423af6ab5fSopenharmony_ciir::ClassDeclaration *ClassBuilder::Build(parser::Program *program) &&
433af6ab5fSopenharmony_ci{
443af6ab5fSopenharmony_ci    auto *allocator = checker_->Allocator();
453af6ab5fSopenharmony_ci    ArenaVector<ir::AstNode *> classBody(allocator->Adapter());
463af6ab5fSopenharmony_ci
473af6ab5fSopenharmony_ci    BuildFields(classBody);
483af6ab5fSopenharmony_ci    BuildMethods(classBody);
493af6ab5fSopenharmony_ci
503af6ab5fSopenharmony_ci    // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint)
513af6ab5fSopenharmony_ci    auto *classId = checker_->AllocNode<ir::Identifier>(className_, allocator);
523af6ab5fSopenharmony_ci    classId->SetReference();
533af6ab5fSopenharmony_ci
543af6ab5fSopenharmony_ci    // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint)
553af6ab5fSopenharmony_ci    auto *classDef = checker_->AllocNode<ir::ClassDefinition>(
563af6ab5fSopenharmony_ci        util::StringView(), classId, nullptr, nullptr, ArenaVector<ir::TSClassImplements *>(allocator->Adapter()),
573af6ab5fSopenharmony_ci        nullptr, superClass_, ArenaVector<ir::AstNode *>(allocator->Adapter()), classModifiers_, modifierFlags_,
583af6ab5fSopenharmony_ci        ToLanguage(program->Extension()));
593af6ab5fSopenharmony_ci
603af6ab5fSopenharmony_ci    // Set parents for all class'es fields and methods.
613af6ab5fSopenharmony_ci    classDef->AddProperties(std::move(classBody));
623af6ab5fSopenharmony_ci
633af6ab5fSopenharmony_ci    // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint)
643af6ab5fSopenharmony_ci    auto *classDecl = checker_->AllocNode<ir::ClassDeclaration>(classDef, allocator);
653af6ab5fSopenharmony_ci    // Declare everything as exported for correct import resolution.
663af6ab5fSopenharmony_ci    classDecl->AddModifier(ir::ModifierFlags::EXPORT);
673af6ab5fSopenharmony_ci
683af6ab5fSopenharmony_ci    auto *programAst = program->Ast();
693af6ab5fSopenharmony_ci    classDecl->SetParent(programAst);
703af6ab5fSopenharmony_ci    // Here we assume that global statements of the passed `program` are not currently checked, so that
713af6ab5fSopenharmony_ci    // insertion is safe.
723af6ab5fSopenharmony_ci    programAst->Statements().push_back(classDecl);
733af6ab5fSopenharmony_ci
743af6ab5fSopenharmony_ci    return classDecl;
753af6ab5fSopenharmony_ci}
763af6ab5fSopenharmony_ci
773af6ab5fSopenharmony_civoid ClassBuilder::BuildFields(ArenaVector<ir::AstNode *> &classBody)
783af6ab5fSopenharmony_ci{
793af6ab5fSopenharmony_ci    const auto &pf = cda_.GetPandaFile();
803af6ab5fSopenharmony_ci
813af6ab5fSopenharmony_ci    cda_.EnumerateFields([&](panda_file::FieldDataAccessor &fda) -> void {
823af6ab5fSopenharmony_ci        const char *name = utf::Mutf8AsCString(pf.GetStringData(fda.GetNameId()).data);
833af6ab5fSopenharmony_ci
843af6ab5fSopenharmony_ci        auto *typeNode = helpers::PandaTypeToTypeNode(pf, fda, checker_);
853af6ab5fSopenharmony_ci        ASSERT(typeNode);
863af6ab5fSopenharmony_ci
873af6ab5fSopenharmony_ci        auto *field = helpers::CreateClassProperty(checker_, name, typeNode, helpers::GetModifierFlags(fda, true));
883af6ab5fSopenharmony_ci        classBody.push_back(field);
893af6ab5fSopenharmony_ci    });
903af6ab5fSopenharmony_ci}
913af6ab5fSopenharmony_ci
923af6ab5fSopenharmony_civoid ClassBuilder::BuildMethods(ArenaVector<ir::AstNode *> &classBody)
933af6ab5fSopenharmony_ci{
943af6ab5fSopenharmony_ci    cda_.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) -> void {
953af6ab5fSopenharmony_ci        auto *method = MethodBuilder(checker_, mda, modifierFlags_).Build();
963af6ab5fSopenharmony_ci        classBody.push_back(method);
973af6ab5fSopenharmony_ci    });
983af6ab5fSopenharmony_ci}
993af6ab5fSopenharmony_ci
1003af6ab5fSopenharmony_ci}  // namespace ark::es2panda::evaluate
101