• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param : 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