1/** 2 * Copyright (c) 2023-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 "structLowering.h" 17#include "checker/ETSchecker.h" 18#include "ir/base/classDefinition.h" 19#include "ir/base/classProperty.h" 20#include "ir/astNode.h" 21#include "ir/expression.h" 22#include "ir/opaqueTypeNode.h" 23#include "ir/expressions/identifier.h" 24#include "ir/statements/classDeclaration.h" 25#include "ir/ts/tsAsExpression.h" 26#include "type_helper.h" 27 28namespace ark::es2panda::compiler { 29 30const char *const STRUCT_CLASS_NAME = "CommonStruct0"; 31 32ir::ETSTypeReference *CreateStructTypeReference(checker::ETSChecker *checker, 33 ir::ETSStructDeclaration *etsStrucDeclaration) 34{ 35 auto *allocator = checker->Allocator(); 36 37 ArenaVector<ir::TypeNode *> params(allocator->Adapter()); 38 39 ir::TSTypeParameterInstantiation *typeParamSelfInst = nullptr; 40 41 if (etsStrucDeclaration->Definition()->TypeParams() != nullptr && 42 !etsStrucDeclaration->Definition()->TypeParams()->Params().empty()) { 43 ArenaVector<ir::TypeNode *> selfParams(allocator->Adapter()); 44 ir::ETSTypeReferencePart *referencePart = nullptr; 45 46 for (const auto ¶m : etsStrucDeclaration->Definition()->TypeParams()->Params()) { 47 auto *identRef = checker->AllocNode<ir::Identifier>(param->AsTSTypeParameter()->Name()->Name(), allocator); 48 identRef->AsIdentifier()->SetReference(); 49 50 referencePart = checker->AllocNode<ir::ETSTypeReferencePart>(identRef, nullptr, nullptr); 51 52 auto *typeReference = checker->AllocNode<ir::ETSTypeReference>(referencePart); 53 54 selfParams.push_back(typeReference); 55 } 56 57 typeParamSelfInst = checker->AllocNode<ir::TSTypeParameterInstantiation>(std::move(selfParams)); 58 } 59 60 auto *identSelfRef = 61 checker->AllocNode<ir::Identifier>(etsStrucDeclaration->Definition()->Ident()->Name(), allocator); 62 identSelfRef->AsIdentifier()->SetReference(); 63 64 auto *referenceSelfPart = checker->AllocNode<ir::ETSTypeReferencePart>(identSelfRef, typeParamSelfInst, nullptr); 65 66 auto *selfTypeReference = checker->AllocNode<ir::ETSTypeReference>(referenceSelfPart); 67 68 params.push_back(selfTypeReference); 69 70 auto *typeParamInst = checker->AllocNode<ir::TSTypeParameterInstantiation>(std::move(params)); 71 72 auto *identRef = checker->AllocNode<ir::Identifier>(util::StringView(STRUCT_CLASS_NAME), allocator); 73 identRef->AsIdentifier()->SetReference(); 74 auto *referencePart = checker->AllocNode<ir::ETSTypeReferencePart>(identRef, typeParamInst, nullptr); 75 76 auto *typeReference = checker->AllocNode<ir::ETSTypeReference>(referencePart); 77 78 return typeReference; 79} 80 81using AstNodePtr = ir::AstNode *; 82 83bool StructLowering::Perform(public_lib::Context *ctx, parser::Program *program) 84{ 85 for (auto &[_, ext_programs] : program->ExternalSources()) { 86 (void)_; 87 for (auto *extProg : ext_programs) { 88 Perform(ctx, extProg); 89 } 90 } 91 92 checker::ETSChecker *checker = ctx->checker->AsETSChecker(); 93 94 program->Ast()->TransformChildrenRecursively( 95 [checker](ir::AstNode *ast) -> AstNodePtr { 96 if (ast->IsETSStructDeclaration()) { 97 auto *typeRef = CreateStructTypeReference(checker, ast->AsETSStructDeclaration()); 98 ast->AsETSStructDeclaration()->Definition()->SetSuper(typeRef); 99 ast->AsETSStructDeclaration()->Definition()->AddModifier(ir::ModifierFlags::FINAL); 100 } 101 102 return ast; 103 }, 104 Name()); 105 106 return true; 107} 108 109} // namespace ark::es2panda::compiler 110