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 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
81 using AstNodePtr = ir::AstNode *;
82
Perform(public_lib::Context * ctx,parser::Program * program)83 bool 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