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
28 namespace ark::es2panda::compiler {
29
30 const char *const STRUCT_CLASS_NAME = "CommonStruct0";
31
CreateStructTypeReference(checker::ETSChecker * checker,ir::ETSStructDeclaration * etsStrucDeclaration)32 ir::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
49 referencePart = checker->AllocNode<ir::ETSTypeReferencePart>(identRef, nullptr, nullptr);
50
51 auto *typeReference = checker->AllocNode<ir::ETSTypeReference>(referencePart);
52
53 selfParams.push_back(typeReference);
54 }
55
56 typeParamSelfInst = checker->AllocNode<ir::TSTypeParameterInstantiation>(std::move(selfParams));
57 }
58
59 auto *identSelfRef =
60 checker->AllocNode<ir::Identifier>(etsStrucDeclaration->Definition()->Ident()->Name(), allocator);
61
62 auto *referenceSelfPart = checker->AllocNode<ir::ETSTypeReferencePart>(identSelfRef, typeParamSelfInst, nullptr);
63
64 auto *selfTypeReference = checker->AllocNode<ir::ETSTypeReference>(referenceSelfPart);
65
66 params.push_back(selfTypeReference);
67
68 auto *typeParamInst = checker->AllocNode<ir::TSTypeParameterInstantiation>(std::move(params));
69
70 auto *identRef = checker->AllocNode<ir::Identifier>(util::StringView(STRUCT_CLASS_NAME), allocator);
71
72 auto *referencePart = checker->AllocNode<ir::ETSTypeReferencePart>(identRef, typeParamInst, nullptr);
73
74 auto *typeReference = checker->AllocNode<ir::ETSTypeReference>(referencePart);
75
76 return typeReference;
77 }
78
79 using AstNodePtr = ir::AstNode *;
80
Perform(public_lib::Context * ctx,parser::Program * program)81 bool StructLowering::Perform(public_lib::Context *ctx, parser::Program *program)
82 {
83 for (auto &[_, ext_programs] : program->ExternalSources()) {
84 (void)_;
85 for (auto *extProg : ext_programs) {
86 Perform(ctx, extProg);
87 }
88 }
89
90 checker::ETSChecker *checker = ctx->checker->AsETSChecker();
91
92 program->Ast()->TransformChildrenRecursively(
93 [checker](ir::AstNode *ast) -> AstNodePtr {
94 if (ast->IsETSStructDeclaration()) {
95 auto *typeRef = CreateStructTypeReference(checker, ast->AsETSStructDeclaration());
96 ast->AsETSStructDeclaration()->Definition()->SetSuper(typeRef);
97 ast->AsETSStructDeclaration()->Definition()->AddModifier(ir::ModifierFlags::FINAL);
98 }
99
100 return ast;
101 },
102 Name());
103
104 return true;
105 }
106
107 } // namespace ark::es2panda::compiler
108