1 /*
2 * Copyright (c) 2021-2025 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 "etsFunctionType.h"
17
18 #include "checker/TSchecker.h"
19 #include "checker/ETSchecker.h"
20 #include "compiler/core/ETSGen.h"
21 #include "compiler/core/pandagen.h"
22
23 namespace ark::es2panda::ir {
TransformChildren(const NodeTransformer & cb,std::string_view transformationName)24 void ETSFunctionType::TransformChildren(const NodeTransformer &cb, std::string_view transformationName)
25 {
26 signature_.TransformChildren(cb, transformationName);
27 for (auto *&it : VectorIterationGuard(Annotations())) {
28 if (auto *transformedNode = cb(it); it != transformedNode) {
29 it->SetTransformedNode(transformationName, transformedNode);
30 it = transformedNode->AsAnnotationUsage();
31 }
32 }
33 }
34
Iterate(const NodeTraverser & cb) const35 void ETSFunctionType::Iterate(const NodeTraverser &cb) const
36 {
37 signature_.Iterate(cb);
38 for (auto *it : VectorIterationGuard(Annotations())) {
39 cb(it);
40 }
41 }
42
Dump(ir::AstDumper * dumper) const43 void ETSFunctionType::Dump(ir::AstDumper *dumper) const
44 {
45 const char *throwMarker = nullptr;
46 if (IsThrowing()) {
47 throwMarker = "throws";
48 } else if (IsRethrowing()) {
49 throwMarker = "rethrows";
50 }
51 dumper->Add({{"type", "ETSFunctionType"},
52 {"params", signature_.Params()},
53 {"typeParameters", AstDumper::Optional(signature_.TypeParams())},
54 {"returnType", signature_.ReturnType()},
55 {"throwMarker", AstDumper::Optional(throwMarker)},
56 {"annotations", AstDumper::Optional(Annotations())}});
57 }
58
Dump(ir::SrcDumper * dumper) const59 void ETSFunctionType::Dump(ir::SrcDumper *dumper) const
60 {
61 for (auto *anno : Annotations()) {
62 anno->Dump(dumper);
63 }
64 dumper->Add("((");
65 for (auto *param : Params()) {
66 param->Dump(dumper);
67 if (param != Params().back()) {
68 dumper->Add(", ");
69 }
70 }
71 dumper->Add(")");
72
73 if (TypeParams() != nullptr) {
74 TypeParams()->Dump(dumper);
75 }
76
77 if (ReturnType() != nullptr) {
78 dumper->Add("=> ");
79 ReturnType()->Dump(dumper);
80 }
81
82 if (IsThrowing()) {
83 dumper->Add(" throws");
84 } else if (IsRethrowing()) {
85 dumper->Add(" rethrows");
86 }
87
88 dumper->Add(")");
89 }
90
Compile(compiler::PandaGen * pg) const91 void ETSFunctionType::Compile(compiler::PandaGen *pg) const
92 {
93 pg->GetAstCompiler()->Compile(this);
94 }
95
Compile(compiler::ETSGen * etsg) const96 void ETSFunctionType::Compile(compiler::ETSGen *etsg) const
97 {
98 etsg->GetAstCompiler()->Compile(this);
99 }
100
Check(checker::TSChecker * checker)101 checker::Type *ETSFunctionType::Check(checker::TSChecker *checker)
102 {
103 return checker->GetAnalyzer()->Check(this);
104 }
105
GetType(checker::TSChecker * checker)106 checker::Type *ETSFunctionType::GetType([[maybe_unused]] checker::TSChecker *checker)
107 {
108 return nullptr;
109 }
110
Check(checker::ETSChecker * checker)111 checker::VerifiedType ETSFunctionType::Check(checker::ETSChecker *checker)
112 {
113 return {this, checker->GetAnalyzer()->Check(this)};
114 }
115
GetType(checker::ETSChecker * checker)116 checker::Type *ETSFunctionType::GetType(checker::ETSChecker *checker)
117 {
118 return Check(checker);
119 }
120
Clone(ArenaAllocator * const allocator,AstNode * const parent)121 ETSFunctionType *ETSFunctionType::Clone(ArenaAllocator *const allocator, AstNode *const parent)
122 {
123 ArenaVector<Expression *> paramsClone(allocator->Adapter());
124
125 for (auto *const param : signature_.Params()) {
126 paramsClone.emplace_back(param->Clone(allocator, nullptr)->AsExpression());
127 }
128
129 auto *const typeParamsClone =
130 signature_.TypeParams() != nullptr
131 ? signature_.TypeParams()->Clone(allocator, nullptr)->AsTSTypeParameterDeclaration()
132 : nullptr;
133 auto *const returnTypeClone =
134 signature_.ReturnType() != nullptr ? signature_.ReturnType()->Clone(allocator, nullptr)->AsTypeNode() : nullptr;
135
136 auto *const clone = allocator->New<ETSFunctionType>(
137 FunctionSignature(typeParamsClone, std::move(paramsClone), returnTypeClone), funcFlags_, allocator);
138
139 if (typeParamsClone != nullptr) {
140 typeParamsClone->SetParent(clone);
141 }
142
143 if (returnTypeClone != nullptr) {
144 returnTypeClone->SetParent(clone);
145 }
146
147 for (auto *param : clone->Params()) {
148 param->SetParent(clone);
149 }
150
151 if (parent != nullptr) {
152 clone->SetParent(parent);
153 }
154
155 if (!Annotations().empty()) {
156 ArenaVector<AnnotationUsage *> annotationUsages {allocator->Adapter()};
157 for (auto *annotationUsage : Annotations()) {
158 ES2PANDA_ASSERT(annotationUsage->Clone(allocator, clone));
159 annotationUsages.push_back(annotationUsage->Clone(allocator, clone)->AsAnnotationUsage());
160 }
161 clone->SetAnnotations(std::move(annotationUsages));
162 }
163
164 // If the scope is set to empty, it will result in the inability to retrieve the scope after clone,
165 // and an error cannot find type will be reported
166 clone->SetScope(this->scope_);
167
168 return clone;
169 }
170 } // namespace ark::es2panda::ir
171